package com.kly.sc.api.application.controller.user;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.base.services.redis.RedisClient;
import com.fqgj.common.api.Page;
import com.fqgj.common.api.Response;
import com.fqgj.common.api.annotations.ParamsValidate;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.kly.dto.MemberDto;
import com.kly.dto.ProductBenefitDto;
import com.kly.dto.UserVasPurchasesDto;
import com.kly.enums.Benefits;
import com.kly.enums.ProductCategory;
import com.kly.sc.api.application.annos.InitUser;
import com.kly.sc.api.application.annos.SignIgnore;
import com.kly.sc.api.application.annos.UserBenefitControl;
import com.kly.sc.api.application.annos.VisitorAccessible;
import com.kly.sc.api.application.constant.ApiRedisKeys;
import com.kly.sc.api.application.consts.Constants;
import com.kly.sc.api.application.controller.user.request.*;
import com.kly.sc.api.application.controller.user.response.*;
import com.kly.sc.api.application.enums.ApiResultStatus;
import com.kly.sc.api.application.helper.RequestLocalInfo;
import com.kly.sc.api.application.service.user.BenefitService;
import com.kly.sc.api.application.service.utils.BaseComponent;
import com.kly.sc.api.application.utils.JwtUtils;
import com.kly.sc.api.application.utils.RpcUtils;
import com.kly.sc.api.infras.exception.ApplicationException;
import com.kly.sc.api.infras.handler.ApiResponse;
import com.kly.sc.api.integration.impl.RCClientImpl;
import com.kly.service.ProductService;
import com.kly.service.UserVasPurchasesService;
import com.kly.user.constant.RedisKey;
import com.kly.user.dto.*;
import com.kly.user.enums.*;
import com.kly.user.service.OtherService;
import com.kly.user.service.UserService;
import com.kly.user.service.WlmService;
import io.rong.models.Result;
import io.rong.models.response.UserResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author linqu
 */
@Slf4j
@RestController
@RequestMapping("/api/users")
@Api(value = "用户相关接口", tags = {"用户相关接口"})
public class UserController extends BaseComponent {


    @NacosValue(value = "${app.configs.appConfig.sparksy.appVersionName}", autoRefreshed = true)
    private String appVersionName;
//    @NacosValue(value = "${user.wlmWindow}", autoRefreshed = true)
//    private String wlmWindow;
    @NacosValue(value = "${removeFlag:false}", autoRefreshed = true)
    private boolean removeFlag;
    @NacosValue(value = "${homepage.newUser.turnOns}", autoRefreshed = true)
    private Integer newUserSize;
    @NacosValue(value = "${homepage.oldUser.turnOns}", autoRefreshed = true)
    private Integer oldUserSize;
    @Resource
    OtherService otherService;
    private static final Log logger = LogFactory.getLog(UserController.class);
    @Resource
    private UserService userService;
    @Resource
    private RCClientImpl rcClient;
    @Resource
    private WlmService wlmService;
    @Resource
    RedisClient redisClient;
    private static final String touchuAppName = "com.kly.touchu";
    @Resource
    UserVasPurchasesService userVasPurchasesService;
    @Resource
    ProductService productService;
    @Resource
    BenefitService benefitService;


    @RequestMapping("/{mobile}/verifyCode/send")
    @SignIgnore
    @VisitorAccessible
    public ApiResponse sendVerifyCode(@PathVariable String mobile) {

        return new ApiResponse();
    }


    @ResponseBody
    @RequestMapping(value = "/changeUserInfo")
    public Response changeUserInfo(@RequestBody UserChangeReq userChange) {
        String nickName = userChange.getNickName();
        String avatarUrl = null;
        if (StringUtils.isNotEmpty(userChange.getAvatarUrl())) {
            avatarUrl = otherService.getFullImageUrl(userChange.getAvatarUrl());
        }
        String token = RequestLocalInfo.getRequestBasicInfo().getToken();
        String userCode = JwtUtils.getAuthentication(token).getName();
        //如果昵称或者头像不为空则修改融云用户信息
        if (!StringUtils.isEmpty(nickName) || !StringUtils.isEmpty(avatarUrl)) {
            UserResult userInfo = rcClient.getUserInfo(userCode);
            //如果存在用户信息则修改
            if (ApiResultStatus.OK.getCode().equals(userInfo.getCode())) {
                nickName = getOrElse(nickName, userInfo.getUserName());
                avatarUrl = getOrElse(avatarUrl, userInfo.getUserPortrait());
                rcClient.register(userCode, nickName, avatarUrl);
            }
        }
        return userService.changeUserInfo(UserChangeReq.getUserInfoDto(userChange), userCode);
    }

    private String getOrElse(String value, String defaultValue) {
        return Optional.ofNullable(value)
                .filter(str -> !str.isEmpty())
                .orElse(defaultValue);
    }

    @RequestMapping(value = "/initUserInfo")
    @InitUser
    @ApiOperation(value = "个人信息初始化", notes = "个人信息初始化")
    public Response initUserInfo(@Valid @RequestBody UserChangeReq userChange, BindingResult results) {
        if (results.hasErrors()) {
            return Response.error(ResultStatus.MISSING_USER_INFORMATION,
                    results.getAllErrors().get(0).getDefaultMessage());
        }
        String token = RequestLocalInfo.getRequestBasicInfo().getToken();
        String userCode = JwtUtils.getAuthentication(token).getName();
        String appId = RequestLocalInfo.getRequestBasicInfo().getApplicationID();

        if (StringUtils.isEmpty(userChange.getAvatarUrl())) {
            List<String> images = Lists.newArrayList();
            if (StringUtils.isNotEmpty(appId) && appId.equals(AppCodeEnum.TOUCHU.getPackageName())) {
                if (GenderEnum.MAN.getType() == userChange.getGender()) {
                    userChange.setAvatarUrl("/tounchu/icons/avatar-man.png");
                    images.add("/tounchu/icons/avatar-man.png");
                } else if (GenderEnum.WOMAN.getType() == userChange.getGender()) {
                    userChange.setAvatarUrl("/tounchu/icons/avatar-famel.png");
                    images.add("/tounchu/icons/avatar-famel.png");
                } else {
                    userChange.setAvatarUrl("/icons/avatar-unknow.png");
                    images.add("/tounchu/icons/avatar-unknow.png");
                }
            }
            else if (StringUtils.isNotEmpty(appId) && appId.equals(AppCodeEnum.PP.getPackageName())) {
                if (GenderEnum.MAN.getType() == userChange.getGender()) {
                    userChange.setAvatarUrl("/icons/avatar/man.jpg");
                    images.add("/passionpulse/icons/avatar/man.jpg");
                } else if (GenderEnum.WOMAN.getType() == userChange.getGender()) {
                    userChange.setAvatarUrl("/icons/avatar/gril.jpg");
                    images.add("/passionpulse/icons/avatar/gril.jpg");
                } else {
                    userChange.setAvatarUrl("/icons/avatar/cool.jpg");
                    images.add("/passionpulse/icons/avatar/cool.jpg");
                }
            }
            else {
                if (GenderEnum.MAN.getType() == userChange.getGender()) {
                    userChange.setAvatarUrl("/icons/avatar/man.jpg");
                    images.add("/icons/avatar/man.jpg");
                } else if (GenderEnum.WOMAN.getType() == userChange.getGender()) {
                    userChange.setAvatarUrl("/icons/avatar/woman.jpg");
                    images.add("/icons/avatar/woman.jpg");
                } else {
                    userChange.setAvatarUrl("/icons/avatar/queer.jpg");
                    images.add("/icons/avatar/queer.jpg");
                }
            }

            userChange.setImages(images);
        }

        userChange.setAvatarUrl(otherService.getFullImageUrl(userChange.getAvatarUrl()));
        if (Objects.isNull(userChange.getLookingFor())) {
            if (GenderEnum.MAN.getType() == userChange.getGender()) {
                userChange.setLookingFor(GenderEnum.WOMAN.getType());
            }
            if (GenderEnum.WOMAN.getType() == userChange.getGender()) {
                userChange.setLookingFor(GenderEnum.MAN.getType());
            }
            if (GenderEnum.UNKNOWN.getType() == userChange.getGender()) {
                userChange.setLookingFor(GenderEnum.OTHERS.getType());
            }
        }

        Response<UserInfoDto> userInfoDtoResponse = userService.changeUserInfo(UserChangeReq.getUserInfoDto(userChange), userCode);
        if (Objects.nonNull(userInfoDtoResponse) && userInfoDtoResponse.isSuccess()) {
            return Response.ok(userInfoDtoResponse.getData());
        }
        return Response.error(userInfoDtoResponse.getMsg());
    }




    /**
     * 根据用户编码获取用户信息，如果用户编码为空则获取当前用户的信息，并且如果是获取当前用户的信息则会丰富会员信息。
     *
     * @param request 包含用户编码的请求
     * @return 用户信息
     */
    @ResponseBody
    @RequestMapping(value = "/userInfo")
    public Response getUserByUserCode(@RequestBody UserCodeRequest request) {

        String userCode = StringUtils.isEmpty(request.getUserCode()) ?
                RequestLocalInfo.getCurrentUser().getUserCode() : request.getUserCode();

        // 获取用户信息
        Response<UserInfoDto> userInfoResponse = userService.getUserByUserCode(userCode, getAppCode());

        final String currentUserCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final UserBaseDto userBaseDto = RpcUtils.getResult(userService.getUserBaseInfo(currentUserCode));

        // 确定用户编码，如果请求中没有提供则默认为当前用户的编码


        // 获取会员信息
        MemberDto memberDto = retrieveMemberFromCacheOrService(userCode);
        boolean isMember = Optional.ofNullable(memberDto).isPresent();

        // 如果是获取当前用户自己的信息并且获取成功，那么进一步获取会员信息并且丰富用户信息
        final UserInfoDto userInfoDto = userInfoResponse.getData();
        if (userInfoResponse.isSuccess() && StringUtils.isEmpty(userCode)) {
            enrichUserInfoWithMembership(userInfoDto, userCode);
        }


        if (userInfoDto != null) {

            userInfoDto.setIsMember(isMember);
            userInfoDto.setMemberCode(Objects.nonNull(memberDto) ? memberDto.getMemberCode() : "");
            userInfoDto.setExpiryDate(Objects.nonNull(memberDto) ? memberDto.getExpiryDate() : null);
            userInfoDto.setAutoRenew(Objects.nonNull(memberDto) ? memberDto.getAutoRenew() : null);
            userInfoDto.setTopTag("Limited-Time Special");
            String inchHeight = userInfoDto.getInchHeight();
            //当查询其他用户信息且对方隐藏了身高则不显示
            if (inchHeight != null && userInfoDto.isHideHeight()) {
                userInfoDto.setInchHeight(null);
            }
            userInfoDto.setEmail(null);
            userInfoDto.setState(null);
            userInfoDto.setCity(null);

            if (Objects.nonNull(userBaseDto.getGpsPrivilege()) && userBaseDto.getGpsPrivilege() == 1) {
                if (userInfoDto.getUserType() == UserType.CHATTER_MODEL.getType()) {
                    userInfoDto.setNearby(1);
                }
            }

            List<UserTurnOnsDto> turnOnsList = userInfoDto.getTurnOnsList();

            // 非当前注册用户只返回selected=1的数据
            if (StringUtils.isNotEmpty(request.getUserCode()) && CollUtil.isNotEmpty(turnOnsList)) {
                userInfoDto.setTurnOnsList(turnOnsList.stream().filter(item -> item.getSelected() != 0).collect(Collectors.toList()));
            } else {
                userInfoDto.setTurnOnsList(turnOnsList);
            }


            if (super.showTurnOns()) {
                userInfoDto.setTurnOnsList(null);
                userInfoDto.setYouAccept(null);
            }

        }

        return Response.ok(UserInfoVO.toVo(userInfoDto));
    }



    /**
     * 使用会员信息丰富用户信息。
     *
     * @param userInfo 用户信息
     * @param userCode 用户编码
     */
    private void enrichUserInfoWithMembership(UserInfoDto userInfo, String userCode) {
        // 从缓存或者服务中获取会员信息
        MemberDto memberDto = retrieveMemberFromCacheOrService(userCode);

        // 如果会员信息存在，则丰富用户信息并且更新缓存
        if (memberDto != null) {
            userInfo.setIsMember(true);
            userInfo.setMemberCode(memberDto.getMemberCode());
            userInfo.setAutoRenew(memberDto.getAutoRenew());
            userInfo.setExpiryDate(memberDto.getExpiryDate());
            userInfo.setMemberDescription(JSON.parseObject(JSON.toJSONString(memberDto.getMemberDescription())));
            userInfo.setTopTag("Limited-time Special");
        }
    }


    @ResponseBody
    @RequestMapping(value = "/userBase")
    public Response getUserBaseInfo(@RequestBody UserCodeRequest request) {
        String userCode = null;
        if (StringUtils.isEmpty(request.getUserCode())) {
            userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        }
        return userService.getUserBaseInfo(userCode);
    }


    @ResponseBody
    @RequestMapping(value = "/getUserInfo")
    public Response getUserInfo(@RequestBody UserCodeRequest request) {

        final String currentUserCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final UserBaseDto currentUser = RpcUtils.getResult(userService.getUserBaseInfo(currentUserCode));
        String userCode = request.getUserCode();
        final UserBaseDto theOtherPersonProfile = RpcUtils.getResult(userService.getUserBaseInfo(userCode));

        int nearby = 0;
        if (Objects.nonNull(currentUser.getGpsPrivilege()) && currentUser.getGpsPrivilege() == 1) {
            if (UserType.CHATTER_MODEL.getType() == theOtherPersonProfile.getUserType()) {
                nearby = 1;
            }
        }
        theOtherPersonProfile.setNearby(nearby);

        final UserBaseRsp userBaseRsp = UserBaseRsp.toRsp(theOtherPersonProfile);
        // 获取flashchat标志
        final Integer sumFc = RpcUtils.getResult(wlmService.sumConnectType(currentUserCode, userCode, ConnectTypeEnum.CONNECT_BY_FC.getCode()));
        userBaseRsp.setFlashchatFlag(sumFc > 0 ? 1 : 0);


        return Response.ok(userBaseRsp);

    }


    @ResponseBody
    @RequestMapping(value = "/interests")
    public Response getUserBaseInfo() {
        final List<InterestDto> resultList = RpcUtils.getResult(otherService.getInterests());
        if (CollectionUtils.isEmpty(resultList)) {
            return Response.ok();
        }

        final List<InterestVO> interests = resultList.stream().map(o -> {
            return InterestVO.builder().interestCode(o.getId()).interest(o.getInterestName()).build();

        }).collect(Collectors.toList());
        return Response.ok(interests);
    }


    @ResponseBody
    @RequestMapping(value = "/userAccount")
    public Response getUserAccount() {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        String mobile = RequestLocalInfo.getCurrentUser().getMobile();
        Response<UserAccountDto> userAccount = userService.getUserAccount(userCode);
        if (userAccount.isSuccess()) {
            Long loginType = redisClient.getNumber(ApiRedisKeys.USER_LOGIN_TYPE.getValue(), userCode);
            UserAccountDto userAccountDto = userAccount.getData();
            userAccountDto.setLoginType(loginType);
            userAccountDto.setMobile(mobile);
            MemberDto memberDto = retrieveMemberFromCacheOrService(userCode);
            if (memberDto != null) {
                userAccountDto.setEffectiveDate(memberDto.getEffectiveDate());
                userAccountDto.setExpiryDate(memberDto.getExpiryDate());
                userAccountDto.setAutoRenew(memberDto.getAutoRenew());
            }

        }
        return userAccount;
    }

    @ResponseBody
    @RequestMapping(value = "/accountBind")
    public Response accountBind(@RequestBody UserAccountDto userAccountDto) {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final UserBaseDto user = RpcUtils.getResult(userService.getUserBaseInfo(userCode));
        if (Objects.isNull(user)) {
            return Response.error("Account not in records!");
        }
        if (StringUtils.isNotEmpty(user.getMobile()) && StringUtils.isNotEmpty(userAccountDto.getMobile())
                && user.getMobile().contains(userAccountDto.getMobile())) {
            return Response.error("Binding failed. Other account have been bound");
        }

        return userService.accountBind(userAccountDto, userCode);

    }




    @ResponseBody
    @RequestMapping(value = "/removeAccount")
    public Response removeAccount(@RequestBody UserAccountDto userAccountDto) {
        if (userAccountDto.getAccountType() == null) {
            return Response.error(ApiResultStatus.PARAMETER_VALIDATION_FAILED);
        }
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        return userService.removeAccount(userCode, userAccountDto.getAccountType());


    }

    @ResponseBody
    @RequestMapping(value = "/removeUser")
    public Response removeUser() {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        return userService.removeUser(userCode);
    }

    @ResponseBody
    @RequestMapping(value = "/removeByEmail")
    @SignIgnore
    public Response removeUser(@RequestBody UserLoginDto userLogin) {
        if (removeFlag) {
            if (StringUtils.isNotEmpty(userLogin.getEmail())) {
                return userService.removeUserAccount(null, userLogin.getEmail());
            }

            if (StringUtils.isNotEmpty(userLogin.getMobile())) {
                return userService.removeUserAccount(userLogin.getMobile(), null);
            }
        }
        return Response.ok();

    }

    @ResponseBody
    @RequestMapping(value = "/getUserBaseInfoByEmail")
    @SignIgnore
    public Response getUserBaseInfoByEmail(@RequestBody UserLoginDto userLogin) {
        if (StringUtils.isNotEmpty(userLogin.getEmail()) && removeFlag) {
            return userService.getUserBaseInfoByEmail(userLogin.getEmail());
        }
        return Response.ok();
    }


    /**
     * 增加WLM数据，
     *
     * @param doUserReq
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/addWlm")
    @ParamsValidate
    @UserBenefitControl(benefit = "browse")
    public Response addWlm(@RequestBody DoUserLikeRequest doUserReq) {

        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final UserInfoDto userInfo = RpcUtils.getResult(userService.getUserByUserCode(userCode));
        if (Objects.isNull(userInfo)) {
            throw new ApplicationException("User not exists!");
        }
        // 拉黑时融云平台同步进行拉黑操作
//        addOrRemoveBlackList(doUserReq, userCode);

        // 添加wlmUser信息
        AddWlmReq req = new AddWlmReq();
        BeanUtils.copyProperties(doUserReq, req);
        req.setUserCode(userCode);

        final AddWlmUserDto result = RpcUtils.getResult(wlmService.addWlmUser(req));
        if (Objects.isNull(result)) {
            return Response.ok();
        }

        // 设置：disLike account
//        addDisLikeUser(doUserReq, userCode, String.valueOf(userInfo.getLookingFor()));

        return Response.ok(AddWlmResponse.builder().userCode(userCode).matched(result.isMatched()).build());
    }

    /**
     * 扣减wlm次数之后添加喜欢
     *
     * @param doUserReq
     */
    public void wlmLIke(DoUserLikeRequest doUserReq) {
        addWlm(doUserReq);
    }

    /**
     * 用户行为接口
     *
     * @param doUserReq
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/addAction")
    @ParamsValidate
    public Response addAction(@RequestBody DoUserOperateRequest doUserReq) {

        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();


        // 拉黑时融云平台同步进行拉黑操作
        addOrRemoveBlackList(doUserReq, userCode);

        // 添加wlmUser信息
        AddWlmReq req = new AddWlmReq();
        BeanUtils.copyProperties(doUserReq, req);
        req.setUserCode(userCode);

        final AddWlmUserDto result = RpcUtils.getResult(wlmService.doAction(req));
        if (Objects.isNull(result)) {
            return Response.ok();
        }

        return Response.ok(AddWlmResponse.builder().userCode(userCode).matched(result.isMatched()).build());
    }

    /**
     * 设置用户newFlag标记
     *
     * @param setNewFlagRequest
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/addNewFlag")
    @ParamsValidate
    public Response addNewFlag(@RequestBody SetNewFlagRequest setNewFlagRequest) {

        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();

        // 添加wlmUser信息
        AddWlmReq req = new AddWlmReq();
        BeanUtils.copyProperties(setNewFlagRequest, req);
        req.setUserCode(userCode);

        final Response response = wlmService.addNewFlag(req);
        if (Objects.nonNull(response) && response.isSuccess()) {
            return Response.ok();
        }

        return Response.error();
    }

    /**
     * 添加、删除黑名单到融云平台
     */
    private void addOrRemoveBlackList(@RequestBody DoUserOperateRequest addWlmRequest, String userCode) {
        Result rongCloudResult = null;

        // 添加黑名单操作
        final ArrayList<Integer> blackList = Lists.newArrayList(UserOpActionEnum.ADD_BLACK_LIST.getType(), UserOpActionEnum.REPORT_USER.getType());
        // 移除黑名单操作
        final ArrayList<Integer> removeBlackList = Lists.newArrayList(UserOpActionEnum.REMOVE_BLACK_LIST.getType());

        if (blackList.contains(addWlmRequest.getOpType())) {
            // 拉黑、举报时，自动设置用户wlm为：不喜欢
            addWlmRequest.setLikeType(LikeEnum.DO_NOT.getType());
            rongCloudResult = rcClient.addBlackList(userCode, Arrays.asList(addWlmRequest.getUserCodeFriend()));
        } else if (removeBlackList.contains(addWlmRequest.getOpType())) {
            rongCloudResult = rcClient.removeBlackList(userCode, Arrays.asList(addWlmRequest.getUserCodeFriend()));
        }

        // 融云平台结果校验
        if (blackList.contains(addWlmRequest.getOpType()) || removeBlackList.contains(addWlmRequest.getOpType())) {
            if (Objects.isNull(rongCloudResult) || rongCloudResult.getCode() != HttpStatus.OK.value()) {
                logger.error("Invoker RC failed! requestParams = " + JSONObject.toJSONString(addWlmRequest));
                throw new ApplicationException("Invoker RC failed!");
            }
        }
    }


    /**
     * wlm用户列表接口
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/wlmList")
    public Response wlmList(@RequestBody WlmUserRequest wlmUserRequest) {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final Page page = buildPage(wlmUserRequest.getPageSize(), wlmUserRequest.getPageNum());
        final List<WlmUserDto> wlmUserDtoList = RpcUtils.getResult(wlmService.wlmList(userCode, page));
        final Integer wlmNum = RpcUtils.getResult(wlmService.wlmNum(userCode));
        Map<String, Object> resp = Maps.newConcurrentMap();
        MemberDto memberDto = retrieveMemberFromCacheOrService(userCode);
        final Integer wlmDefaultNum = getWlmNum();
        if (memberDto != null) {
            resp.put("isMember", true);
        } else {
            resp.put("isMember", false);
        }
        resp.put("wlmUsageNum", getWlmBenefitNum(userCode, wlmDefaultNum));
        resp.put("wlmWindow", "You Got " + wlmDefaultNum + " Free Chances To Like People \"Who Like Me\".");
        resp.put("wlmCount", getWLMNum(userCode));
        if (CollectionUtils.isNotEmpty(wlmUserDtoList)) {
            // 开关打开时，需要对turnOns隐藏处理
            for (WlmUserDto dto : wlmUserDtoList) {
                if (super.showTurnOns()) {
                    dto.setTurnOnsListSize(0);
                }
            }

            resp.put("wlmList", wlmUserDtoList);
            resp.put("wlmNum", wlmNum);
        } else {
            resp.put("wlmList", Lists.newArrayList());
            resp.put("wlmNum", 0);
        }
        resp.put("message", "If you don't unlock it, the Who Likes Me card will expire in 3 days");
        resp.put("wlmGuide", "Freely view those who have crush on you and build sexy relationships quickly \uD83D\uDE09");
        return Response.ok(resp);
    }


    private Integer getWlmNum() {
        final String appCode = RequestLocalInfo.getRequestBasicInfo().getAppCode();
        final String userCode = RequestLocalInfo.getCurrentUser().getUserCode();

        ProductCategory productCategory = benefitService.getProductCategory(userCode, appCode);

        final List<ProductBenefitDto> benefitDtos = RpcUtils.getResult(productService.listProductBenefit(RequestLocalInfo.getRequestBasicInfo().getAppCode(), productCategory.getCode()));
        if (CollectionUtils.isNotEmpty(benefitDtos)) {
            for (ProductBenefitDto dto : benefitDtos) {
                if (Benefits.WHO_LIKES_ME.getBenefitCode() == dto.getBenefitCode()) {
                    return dto.getLimitQuantity();
                }
            }
        }
        return 0;
    }


    private Integer getWlmBenefitNum(String userCode, Integer wlmDefaultNum) {
        // benefitCode: 参见`prod`.benefits 权益表字典
        final List<UserVasPurchasesDto> benefitList = RpcUtils.getResult(userVasPurchasesService.getAllUserBenefits(userCode));
        if (CollectionUtils.isEmpty(benefitList)) {
            return 0;
        }
        final UserVasPurchasesDto userVasPurchasesDto = benefitList.stream().filter(o -> 8 == o.getBenefitCode()).findAny().orElse(null);
        if (userVasPurchasesDto == null) {
            return 0;
        }
        return userVasPurchasesDto.getUsageCount() > 0 ? wlmDefaultNum : 0;
    }

    /**
     * 读取WLM剩余次数
     * @param userCode
     * @return
     */
    private Integer getWLMNum(String userCode) {
        final List<UserVasPurchasesDto> benefitList = RpcUtils.getResult(userVasPurchasesService.getAllUserBenefits(userCode));
        if (CollectionUtils.isEmpty(benefitList)) {
            return 0;
        }
        final UserVasPurchasesDto userVasPurchasesDto = benefitList.stream().filter(o -> 8 == o.getBenefitCode()).findAny().orElse(null);
        if (userVasPurchasesDto == null) {
            return 0;
        }
        return userVasPurchasesDto.getUsageCount();
    }


    /**
     * 双方互相Like， match成功后建联
     *
     * @return 返回建联成功后的wlm信息
     */
    @ResponseBody
    @RequestMapping(value = "/matchedList")
    public Response matchedList(@RequestBody MatchedWlmUserRequest matchedWlmUserRequest) {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();
        final Page page = buildPage(matchedWlmUserRequest.getPageSize(), matchedWlmUserRequest.getPageNum());
        final List<WlmUserDto> wlmUserDtoList = RpcUtils.getResult(wlmService.queryLikeEachOtherList(userCode, page));
        if (CollectionUtils.isNotEmpty(wlmUserDtoList)) {
            final List<MatchedWlmUserResponse> matchedWlmUserResponses = wlmUserDtoList.stream().map(o -> {
                MatchedWlmUserResponse vo = MatchedWlmUserResponse.builder().build();
                BeanUtils.copyProperties(o, vo);
                return vo;
            }).collect(Collectors.toList());
            return Response.ok(matchedWlmUserResponses);

        }
        return Response.ok();
    }

    private Page buildPage(Integer pageSize, Integer pageNum) {
        Page page = new Page();
        page.setPageSize(pageSize);
        page.setCurrentPage(pageNum);
        return page;
    }


    /**
     * 私密照列表接口
     */
    @ResponseBody
    @RequestMapping(value = "/albums")
    public Response albums(@RequestBody UserImagesRequest request) {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();

        final AlbumDto result = RpcUtils.getResult(
                userService.getUserImages(userCode, request.getType()));

//        if (StringUtils.isEmpty(result.getAlbumCode())) {
//            throw new ApplicationException("The album did not exists");
//        }

        return Response.ok(result);
    }

    /**
     * 转私密操作接口
     */
    @ResponseBody
    @RequestMapping(value = "/addAlbums")
    @ParamsValidate
    public Response addAlbums(@RequestBody AddImagesRequest request) {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();

        AlbumDto albumDto = RpcUtils.getResult(
                userService.getUserImages(userCode, request.getType()));

        // 若不存在相册， 需要创建相册
        if (Objects.nonNull(albumDto) && StringUtils.isEmpty(albumDto.getAlbumCode())) {
            albumDto = RpcUtils.getResult(userService.createAlbums(userCode, request.getType()));
        }

        // 添加相片
        final ImagesObjDto result = RpcUtils.getResult(
                userService.addImageToAlbums(userCode, request.getType(), request.getImageCode(), request.getImageUrl(), albumDto.getAlbumCode(), request.getVideoLength()));

        result.setImageUrl(otherService.getFullImageUrl(request.getImageUrl()));

        return Response.ok(result);
    }

    /**
     * 转私密操作接口
     */
    @ResponseBody
    @RequestMapping(value = "/removeImages")
    @ParamsValidate
    public Response removeImages(@RequestBody RemoveImagesRequest request) {
        String userCode = RequestLocalInfo.getCurrentUser().getUserCode();

        AlbumDto albumDto = RpcUtils.getResult(
                userService.getUserImages(userCode, request.getType()));

        if (Objects.isNull(albumDto)) {
            throw new ApplicationException("The album does not exists");
        }
        if (!albumDto.getAlbumCode().equals(request.getAlbumCode())) {
            throw new ApplicationException("Illegal album error");
        }


        // 添加相片
        RpcUtils.getResult(userService.removeImageFromAlbums(userCode, request.getImageCode(), albumDto.getAlbumCode()));

        return Response.ok(request);
    }


    /**
     * 往缓存中添加喜欢或不喜欢用户
     *
     * @param addWlmRequest 喜欢或不喜欢用户
     */
    private void addDisLikeUser(DoUserLikeRequest addWlmRequest, String userCode, String lookingFor) {
        try {
            if (LikeEnum.DO_NOT.getType() == addWlmRequest.getLikeType()) {
                final Set<String> disLikeUsers = redisClient.sMembers(RedisKey.WLM_DISLIKE, userCode, String.valueOf(lookingFor));
                redisClient.sAdd(RedisKey.WLM_DISLIKE, addWlmRequest.getUserCodeFriend(), userCode, String.valueOf(lookingFor));
                if (CollectionUtils.isEmpty(disLikeUsers)) {
                    redisClient.expire(RedisKey.WLM_DISLIKE, Constants.EFFECTIVE_IN_72_HOURS, userCode, String.valueOf(lookingFor));
                }
            }

            if (LikeEnum.LIKE.getType() == addWlmRequest.getLikeType()) {
                final Set<String> likeUsers = redisClient.sMembers(RedisKey.WLM_LIKE, userCode, String.valueOf(lookingFor));
                redisClient.sAdd(RedisKey.WLM_LIKE, addWlmRequest.getUserCodeFriend(), userCode, String.valueOf(lookingFor));
                if (CollectionUtils.isEmpty(likeUsers)) {
                    redisClient.expire(RedisKey.WLM_LIKE, Constants.EFFECTIVE_IN_48_HOURS, userCode, String.valueOf(lookingFor));
                }
            }

        } catch (Exception e) {
            logger.error("Add like or disLike failed, userCode={}", userCode);
        }
    }


}
